package backend

import (
	"fmt"

	"gopkg.in/mgo.v2"
//	"gopkg.in/mgo.v2/bson"

	/*
		"encoding/json"
	*/)

const (
	COrgs  string = "orgs"
	CUsers string = "users"
)

var (
	MongoSession *mgo.Session
	DB           *mgo.Database
	err          error
	dbName       string   = "toolDB"
	Cache                 = make(map[string]interface{})
	adminRoles   []string = []string{"admin", "editor", "user"}
	editorRoles  []string = []string{"editor"}

)

func MongoMocks() {

	s, u := GetColl(nil, "users")
	_, o := GetColl(s, "orgs")
	defer s.Close()

	admin := &User{}
	err := u.FindId("100").One(admin)
	fmt.Println("found admin in mongo: ", admin)
	if admin.Id == "100" {
		//return
	}

	admin = &User{Id: "100", Name: "Admin", Email: "b", Password: "b", Roles: []string{"admin", "editor"}}
	Cache["user_"+admin.Id] = admin
	Cache["u_mail_"+admin.Email] = admin

	err = u.Insert(admin)
	if err != nil {
		fmt.Println("failed inserting admin user: ", err)
	}

	for i := 0; i < 10; i = i + 1 {
		s := fmt.Sprintf("user_%d", i)
		user := &User{Id: s, Name: s, Email: "e" + fmt.Sprintf("%d", i), Roles: editorRoles}
		Cache[s] = user
		Cache["u_mail_"+user.Email] = user
		u.Insert(user)
	}

	//add dummy organization
	org := &Org{Id: "1", Name: "SanaTech", Email: "ibm@eg", Url: "ibm.com", Password: "pass"}
	Cache["org_"+org.Id] = org
	o.Insert(org)
}

func Connect(url string) *mgo.Session {
	if url == "" {
		url = "localhost"
	}
	MongoSession, err = mgo.Dial(url)
	if err != nil {
		panic(err)
	}
	fmt.Printf("Mongo DB connected on URL: %s \n", url)
	return MongoSession
}

// return collection from session, if the passed session is nil a new one 
// is returned
func GetColl(s *mgo.Session, collName string) (*mgo.Session, *mgo.Collection) {
	if s == nil{
		s = MongoSession.Clone()
	}
	db := s.DB(dbName)
	return s, db.C(collName)
}



func Find(s *mgo.Session, coll string, query interface{}, result interface{}, one bool, close bool) (*mgo.Session, interface{}, error){

	var err error
	//use sesion if not nil or return new one
	s, c := GetColl(s, coll)
	if close{
		defer s.Close()
	}

	if one{
		err = c.Find(query).One(result)
	}else{
		err = c.Find(query).All(result)
	}

	return s, result, err
}
/*
func Save(s *mgo.Session, coll string, query interface{}, result interface{}, one bool, close bool) (*mgo.Session, interface{}, error){

	var err error
	//use sesion if not nil or return new one
	s, c := GetColl(s, coll)
	if close{
		defer s.Close()
	}
}
}
*/

